/** KempoApi: The Turloc Toolkit *****************************/
/** *    *                                                  **/
/** **  **  Filename: ArcBall.h                             **/
/**   **    Version:  Common                                **/
/**   **                                                    **/
/**                                                         **/
/**  Arcball class for mouse manipulation.                  **/
/**                                                         **/
/**                                                         **/
/**                                                         **/
/**                                                         **/
/**                              (C) 1999-2003 Tatewake.com **/
/**   History:                                              **/
/**   08/17/2003 - (TJG) - Creation                         **/
/**   09/23/2003 - (TJG) - Bug fix and optimization         **/
/**   09/25/2003 - (TJG) - Version for NeHe Basecode users  **/
/**                                                         **/
/*************************************************************/

#ifndef _ArcBall_h
#define _ArcBall_h


// 8<--Snip here if you have your own math types/funcs-->8 

//Only support assertions in debug builds
#ifdef _DEBUG
# include "assert.h"
#else
# define assert(x) { }
#endif

//Math types derived from the KempoApi tMath library
typedef union Tuple2f_t
{
	struct
	{
		GLfloat X, Y;
	} s;

	GLfloat T[2];
} Tuple2fT;      //A generic 2-element tuple that is represented by single-precision floating point x,y coordinates. 

typedef union Tuple3f_t
{
	struct
	{
		GLfloat X, Y, Z;
	} s;

	GLfloat T[3];
} Tuple3fT;      //A generic 3-element tuple that is represented by single precision-floating point x,y,z coordinates. 

typedef union Tuple4f_t
{
	struct
	{
		GLfloat X, Y, Z, W;
	} s;

	GLfloat T[4];
} Tuple4fT;      //A 4-element tuple represented by single-precision floating point x,y,z,w coordinates. 

typedef union Matrix3f_t
{
		struct
		{
			//column major
			union { GLfloat M00; GLfloat XX; GLfloat SX; };  //XAxis.X and Scale X
			union { GLfloat M10; GLfloat XY;             };  //XAxis.Y
			union { GLfloat M20; GLfloat XZ;             };  //XAxis.Z
			union { GLfloat M01; GLfloat YX;             };  //YAxis.X
			union { GLfloat M11; GLfloat YY; GLfloat SY; };  //YAxis.Y and Scale Y
			union { GLfloat M21; GLfloat YZ;             };  //YAxis.Z
			union { GLfloat M02; GLfloat ZX;             };  //ZAxis.X
			union { GLfloat M12; GLfloat ZY;             };  //ZAxis.Y
			union { GLfloat M22; GLfloat ZZ; GLfloat SZ; };  //ZAxis.Z and Scale Z
		} s;
		GLfloat M[9];
} Matrix3fT;     //A single precision floating point 3 by 3 matrix. 

typedef union Matrix4f_t
{
		struct
		{
			//column major
			union { GLfloat M00; GLfloat XX; GLfloat SX; };  //XAxis.X and Scale X
			union { GLfloat M10; GLfloat XY;             };  //XAxis.Y
			union { GLfloat M20; GLfloat XZ;             };  //XAxis.Z
			union { GLfloat M30; GLfloat XW;             };  //XAxis.W
			union { GLfloat M01; GLfloat YX;             };  //YAxis.X
			union { GLfloat M11; GLfloat YY; GLfloat SY; };  //YAxis.Y and Scale Y
			union { GLfloat M21; GLfloat YZ;             };  //YAxis.Z
			union { GLfloat M31; GLfloat YW;             };  //YAxis.W
			union { GLfloat M02; GLfloat ZX;             };  //ZAxis.X
			union { GLfloat M12; GLfloat ZY;             };  //ZAxis.Y
			union { GLfloat M22; GLfloat ZZ; GLfloat SZ; };  //ZAxis.Z and Scale Z
			union { GLfloat M32; GLfloat ZW;             };  //ZAxis.W
			union { GLfloat M03; GLfloat TX;             };  //Trans.X
			union { GLfloat M13; GLfloat TY;             };  //Trans.Y
			union { GLfloat M23; GLfloat TZ;             };  //Trans.Z
			union { GLfloat M33; GLfloat TW; GLfloat SW; };  //Trans.W and Scale W
		} s;
		GLfloat M[16];
} Matrix4fT;     //A single precision floating point 4 by 4 matrix. 


//"Inherited" types
#define Point2fT    Tuple2fT   //A 2 element point that is represented by single precision floating point x,y coordinates. 

#define Quat4fT     Tuple4fT   //A 4 element unit quaternion represented by single precision floating point x,y,z,w coordinates. 

#define Vector2fT   Tuple2fT   //A 2-element vector that is represented by single-precision floating point x,y coordinates. 
#define Vector3fT   Tuple3fT   //A 3-element vector that is represented by single-precision floating point x,y,z coordinates. 

//Custom math, or speed overrides
#define FuncSqrt    sqrtf

//utility macros
//assuming IEEE-754(GLfloat), which i believe has max precision of 7 bits
# define Epsilon 1.0e-5

void arc_setWidth(int w);
void arc_setHeight(int h);
void arc_map2sphere(int x, int y, Vector3fT *v);
void arc_drag(int x, int y, Quat4fT *q, Vector3fT *EnVec, Vector3fT *StVec);
void Matrix3fSetIdentity(Matrix3fT* NewObj);
void Matrix4fSetRotationFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1);
void Matrix3fSetRotationFromQuat4f(Matrix3fT* NewObj, const Quat4fT* q1);
void Matrix3fMulMatrix3f(Matrix3fT* NewObj, const Matrix3fT* m1);


#endif
